<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="robots" content="noodp" />
        <title>java调用phantomjs爬取网页及快照 - 八月半的研发杂谈</title><meta name="Description" content="MidAug blog java docker hugo"><meta property="og:url" content="https://100180.xyz/posts/20180129/">
  <meta property="og:site_name" content="八月半的研发杂谈">
  <meta property="og:title" content="java调用phantomjs爬取网页及快照">
  <meta property="og:description" content="前言 前阵子遇到一个需求，需要爬取学信网学历的查询结果进行解析并截图留证，利用java完成了爬取的html解析功能后发现截图较为困难。我偶然发">
  <meta property="og:locale" content="en">
  <meta property="og:type" content="article">
  <meta property="article:section" content="posts">
    <meta property="article:published_time" content="2018-01-29T21:11:33+00:00">
    <meta property="article:modified_time" content="2018-01-29T21:11:33+00:00">
    <meta property="article:tag" content="Phantomjs">
    <meta property="article:tag" content="爬虫">
    <meta property="article:tag" content="网页快照">
    <meta property="article:tag" content="Javascript">
    <meta property="article:tag" content="Java">
    <meta property="og:image" content="https://100180.xyz/images/whoami/avatar.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://100180.xyz/images/whoami/avatar.jpg"><meta name="twitter:title" content="java调用phantomjs爬取网页及快照">
<meta name="twitter:description" content="前言 前阵子遇到一个需求，需要爬取学信网学历的查询结果进行解析并截图留证，利用java完成了爬取的html解析功能后发现截图较为困难。我偶然发">
<meta name="application-name" content="MidAug&#39;s  Blog">
<meta name="apple-mobile-web-app-title" content="MidAug&#39;s  Blog"><meta name="theme-color" content="#ffffff"><meta name="msapplication-TileColor" content="#da532c"><link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"><link rel="manifest" href="/site.webmanifest"><link rel="canonical" href="https://100180.xyz/posts/20180129/" /><link rel="prev" href="https://100180.xyz/posts/20171220/" /><link rel="next" href="https://100180.xyz/posts/2018081401/" /><link rel="stylesheet" href="/css/style.min.css"><link rel="preload" href="/lib/fontawesome-free/all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
        <noscript><link rel="stylesheet" href="/lib/fontawesome-free/all.min.css"></noscript><link rel="preload" href="/lib/animate/animate.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
        <noscript><link rel="stylesheet" href="/lib/animate/animate.min.css"></noscript><script type="application/ld+json">
    {
        "@context": "http://schema.org",
        "@type": "BlogPosting",
        "headline": "java调用phantomjs爬取网页及快照",
        "inLanguage": "en",
        "mainEntityOfPage": {
            "@type": "WebPage",
            "@id": "https:\/\/100180.xyz\/posts\/20180129\/"
        },"image": [{
                            "@type": "ImageObject",
                            "url": "https:\/\/100180.xyz\/images\/Apple-Devices-Preview.png",
                            "width":  3200 ,
                            "height":  2048 
                        }],"genre": "posts","keywords": "phantomjs, 爬虫, 网页快照, javascript, java","wordcount":  2167 ,
        "url": "https:\/\/100180.xyz\/posts\/20180129\/","datePublished": "2018-01-29T21:11:33+00:00","dateModified": "2018-01-29T21:11:33+00:00","license": "This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.","publisher": {
            "@type": "Organization",
            "name": "MidAug","logo": "https:\/\/100180.xyz\/images\/whoami\/avatar.jpg"},"author": {
                "@type": "Person",
                "name": "MidAug"
            },"description": ""
    }
    </script></head>
    <body data-header-desktop="fixed" data-header-mobile="auto"><script type="text/javascript">(window.localStorage && localStorage.getItem('theme') ? localStorage.getItem('theme') === 'dark' : ('auto' === 'auto' ? window.matchMedia('(prefers-color-scheme: dark)').matches : 'auto' === 'dark')) && document.body.setAttribute('theme', 'dark');</script>

        <div id="mask"></div><div class="wrapper"><header class="desktop" id="header-desktop">
    <div class="header-wrapper">
        <div class="header-title">
            <a href="/" title="八月半的研发杂谈"><img
        class="lazyload logo"
        src="/svg/loading.min.svg"
        data-src="/favicon/apple-icon-60x60.png"
        data-srcset="/favicon/apple-icon-60x60.png, /favicon/apple-icon-60x60.png 1.5x, /favicon/apple-icon-60x60.png 2x"
        data-sizes="auto"
        alt="/favicon/apple-icon-60x60.png"
        title="/favicon/apple-icon-60x60.png" /><span id="id-1" class="typeit"></span></a>
        </div>
        <div class="menu">
            <div class="menu-inner"><a class="menu-item" href="/posts/"> Posts </a><a class="menu-item" href="/tags/"> Tags </a><a class="menu-item" href="/categories/"> Categories </a><a class="menu-item" href="/about/"> About </a><a class="menu-item" href="/disclaimer/"> Disclaimer </a><a class="menu-item" href="https://github.com/midaug" title="GitHub" rel="noopener noreffer" target="_blank"><i class='fab fa-github fa-fw' aria-hidden='true'></i>  </a><span class="menu-item delimiter"></span><span class="menu-item search" id="search-desktop">
                        <input type="text" placeholder="Search titles or contents..." id="search-input-desktop">
                        <a href="javascript:void(0);" class="search-button search-toggle" id="search-toggle-desktop" title="Search">
                            <i class="fas fa-search fa-fw" aria-hidden="true"></i>
                        </a>
                        <a href="javascript:void(0);" class="search-button search-clear" id="search-clear-desktop" title="Clear">
                            <i class="fas fa-times-circle fa-fw" aria-hidden="true"></i>
                        </a>
                        <span class="search-button search-loading" id="search-loading-desktop">
                            <i class="fas fa-spinner fa-fw fa-spin" aria-hidden="true"></i>
                        </span>
                    </span><a href="javascript:void(0);" class="menu-item theme-switch" title="Switch Theme">
                    <i class="fas fa-adjust fa-fw" aria-hidden="true"></i>
                </a></div>
        </div>
    </div>
</header><header class="mobile" id="header-mobile">
    <div class="header-container">
        <div class="header-wrapper">
            <div class="header-title">
                <a href="/" title="八月半的研发杂谈"><img
        class="lazyload logo"
        src="/svg/loading.min.svg"
        data-src="/favicon/apple-icon-60x60.png"
        data-srcset="/favicon/apple-icon-60x60.png, /favicon/apple-icon-60x60.png 1.5x, /favicon/apple-icon-60x60.png 2x"
        data-sizes="auto"
        alt="/favicon/apple-icon-60x60.png"
        title="/favicon/apple-icon-60x60.png" /><span id="id-2" class="typeit"></span></a>
            </div>
            <div class="menu-toggle" id="menu-toggle-mobile">
                <span></span><span></span><span></span>
            </div>
        </div>
        <div class="menu" id="menu-mobile"><div class="search-wrapper">
                    <div class="search mobile" id="search-mobile">
                        <input type="text" placeholder="Search titles or contents..." id="search-input-mobile">
                        <a href="javascript:void(0);" class="search-button search-toggle" id="search-toggle-mobile" title="Search">
                            <i class="fas fa-search fa-fw" aria-hidden="true"></i>
                        </a>
                        <a href="javascript:void(0);" class="search-button search-clear" id="search-clear-mobile" title="Clear">
                            <i class="fas fa-times-circle fa-fw" aria-hidden="true"></i>
                        </a>
                        <span class="search-button search-loading" id="search-loading-mobile">
                            <i class="fas fa-spinner fa-fw fa-spin" aria-hidden="true"></i>
                        </span>
                    </div>
                    <a href="javascript:void(0);" class="search-cancel" id="search-cancel-mobile">
                        Cancel
                    </a>
                </div><a class="menu-item" href="/posts/" title="">Posts</a><a class="menu-item" href="/tags/" title="">Tags</a><a class="menu-item" href="/categories/" title="">Categories</a><a class="menu-item" href="/about/" title="">About</a><a class="menu-item" href="/disclaimer/" title="">Disclaimer</a><a class="menu-item" href="https://github.com/midaug" title="GitHub" rel="noopener noreffer" target="_blank"><i class='fab fa-github fa-fw' aria-hidden='true'></i></a><a href="javascript:void(0);" class="menu-item theme-switch" title="Switch Theme">
                <i class="fas fa-adjust fa-fw" aria-hidden="true"></i>
            </a></div>
    </div>
</header><div class="search-dropdown desktop">
        <div id="search-dropdown-desktop"></div>
    </div>
    <div class="search-dropdown mobile">
        <div id="search-dropdown-mobile"></div>
    </div><main class="main">
                <div class="container"><div class="toc" id="toc-auto">
            <h2 class="toc-title">Contents</h2>
            <div class="toc-content" id="toc-content-auto"></div>
        </div><article class="page single"><h1 class="single-title animate__animated animate__flipInX">java调用phantomjs爬取网页及快照</h1><div class="post-meta">
            <div class="post-meta-line"><span class="post-author"><a href="/" title="Author" rel="author" class="author"><i class="fas fa-user-circle fa-fw" aria-hidden="true"></i>MidAug</a></span>&nbsp;<span class="post-category">included in <a href="/categories/%E7%88%AC%E8%99%AB/"><i class="far fa-folder fa-fw" aria-hidden="true"></i>爬虫</a></span></div>
            <div class="post-meta-line"><i class="far fa-calendar-alt fa-fw" aria-hidden="true"></i>&nbsp;<time datetime="2018-01-29">2018-01-29</time>&nbsp;<i class="fas fa-pencil-alt fa-fw" aria-hidden="true"></i>&nbsp;2167 words&nbsp;
                <i class="far fa-clock fa-fw" aria-hidden="true"></i>&nbsp;5 minutes&nbsp;</div>
        </div><div class="details toc" id="toc-static"  data-kept="">
                <div class="details-summary toc-title">
                    <span>Contents</span>
                    <span><i class="details-icon fas fa-angle-right" aria-hidden="true"></i></span>
                </div>
                <div class="details-content toc-content" id="toc-content-static"><nav id="TableOfContents">
  <ul>
    <li><a href="#常用内置对象">常用内置对象</a></li>
    <li><a href="#常用api">常用API</a></li>
    <li><a href="#调用方式">调用方式</a></li>
  </ul>

  <ul>
    <li><a href="#configjs-配置文件内容">config.js 配置文件内容</a>
      <ul>
        <li><a href="#配置文件总结">配置文件总结</a></li>
      </ul>
    </li>
    <li><a href="#java封装">java封装</a>
      <ul>
        <li><a href="#java封装总结">java封装总结</a></li>
      </ul>
    </li>
  </ul>
</nav></div>
            </div><div class="content" id="content"><p><img
        class="lazyload"
        src="/svg/loading.min.svg"
        data-src="/images/post/phantomjs.png"
        data-srcset="/images/post/phantomjs.png, /images/post/phantomjs.png 1.5x, /images/post/phantomjs.png 2x"
        data-sizes="auto"
        alt="/images/post/phantomjs.png"
        title="phantomjs-png" /></p>
<!-- more -->
<h1 id="前言">前言</h1>
<p>前阵子遇到一个需求，需要爬取学信网学历的查询结果进行解析并截图留证，利用java完成了爬取的html解析功能后发现截图较为困难。我偶然发现了 phantomjs，可以由服务端去做类似爬虫的操作来爬取html和保存图片，正好满足上述两个需求。</p>
<h1 id="phantomjs">phantomjs</h1>
<p><a href="http://phantomjs.org" target="_blank" rel="noopener noreffer ">官方网站: phantomjs.org</a>
phantomjs 是 一个基于 webkit 内核的无头浏览器，没有 UI 界面。它就是一个浏览器，只是内部的点击、翻页等人为相关操作需要程序设计实现。</p>
<p>提供了 javascript API 接口，可以通过 js 直接与 webkit 内核交互，在此之上可以结合 Java 语言等，通过 Java 调用 js 等相关操作，从而解决了以前 c/c++ 才能比较好的基于 webkit 开发优质采集器的限制。</p>
<p>提供了 windows、linux、mac 等不同 OS 的安装使用包，也就是说可以在不同平台上，二次开发采集项目（爬虫）或是自动项目测试等工作。</p>
<h2 id="常用内置对象">常用内置对象</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// 获得系统操作对象，包括命令行参数、phantomjs系统设置等信息
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;system&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 获取操作dom或web网页的对象，通过它可以打开网页、接收网页内容、request、response参数，其为最核心对象。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;webpage&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 获取文件系统对象，通过它可以操作操作系统的文件操作，包括read、write、move、copy、delete等。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;fs&#39;</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="常用api">常用API</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// 通过page对象通过url链接打开页面，加载完成后回调
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">status</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 当page.open调用时，会首先执行该函数，在此可以预置一些参数或函数，用于后边的回调函数中
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onLoadStarted</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// page的所要加载的资源在加载过程中，失败回调处理
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onResourceError</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resourceError</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// page的所要加载的资源在发起请求时，可以回调该函数
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onResourceRequested</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">requestData</span><span class="p">,</span> <span class="nx">networkRequest</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// page的所要加载的资源在加载过程中，每加载一个相关资源，都会在此先做出响应，
</span></span></span><span class="line"><span class="cl"><span class="c1">// 它相当于http头部分，核心回调对象为response，可以获取本次请求的cookies、userAgent等
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onResourceReceived</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 打印一些输出信息到控制台
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onConsoleMessage</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">msg</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// alert也是无法直接弹出的，但可以回调alert的内容
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onAlert</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">msg</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 当page.open时，http请求（不包括所引起的其它的加载资源）出现了异常，
</span></span></span><span class="line"><span class="cl"><span class="c1">// 如404、no route to web site等，都会在此回调显示。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onError</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">msg</span><span class="p">,</span> <span class="nx">trace</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 当page.open打开的url，或者是在打开过程中进行了跳转，可以在这个函数中回调。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onUrlChanged</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">targetUrl</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 当page.open的目标URL被真正打开后，会在调用open的回调函数前调用该函数，在此可以进行内部的翻页等操作
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">onLoadFinished</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">status</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 在所加载的web page内部执行该函数，像翻页、点击、滑动等，均可在此中执行
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">evaluate</span><span class="p">(</span><span class="kd">function</span><span class="p">(){});</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 将当前page的现状渲染成图片，输出到指定的文件中去。
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="s2">&#34;&#34;</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="调用方式">调用方式</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ /bin/phantomjs <span class="o">[</span>配置文件<span class="o">(</span>js文件<span class="o">)]</span> <span class="o">[</span>参数1<span class="o">]</span> <span class="o">[</span>参数2<span class="o">]</span> <span class="o">[</span>参数3<span class="o">]</span> ...
</span></span></code></pre></td></tr></table>
</div>
</div><h1 id="实现">实现</h1>
<p>java使用java.lang.Runtime调用，接收返回结果进行操作</p>
<h2 id="configjs-配置文件内容">config.js 配置文件内容</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;webpage&#39;</span><span class="p">).</span><span class="nx">create</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">system</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;system&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">ssionid</span> <span class="o">=</span> <span class="nx">system</span><span class="p">.</span><span class="nx">args</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> 
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">address</span> <span class="o">=</span> <span class="nx">system</span><span class="p">.</span><span class="nx">args</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="c1">// 请求地址，url
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">output</span> <span class="o">=</span> <span class="nx">system</span><span class="p">.</span><span class="nx">args</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span> <span class="c1">// 输出
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">pageWidth</span> <span class="o">=</span> <span class="mi">1366</span><span class="p">;</span> <span class="c1">//初始化游览器宽
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">pageHeight</span> <span class="o">=</span> <span class="mi">1080</span><span class="p">;</span> <span class="c1">//初始化游览器高
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">viewportSize</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">width</span><span class="o">:</span> <span class="nx">pageWidth</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span> <span class="nx">pageHeight</span> <span class="p">};</span> <span class="c1">//初始化游览器
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// 添加ssionid至cookie
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">phantom</span><span class="p">.</span><span class="nx">addCookie</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="s1">&#39;name&#39;</span>     <span class="o">:</span> <span class="s1">&#39;JSESSIONID&#39;</span><span class="p">,</span>  
</span></span><span class="line"><span class="cl">  <span class="s1">&#39;value&#39;</span>    <span class="o">:</span> <span class="nx">ssionid</span><span class="p">,</span>  
</span></span><span class="line"><span class="cl">  <span class="s1">&#39;domain&#39;</span>   <span class="o">:</span> <span class="s1">&#39;job.chsi.com.cn&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s1">&#39;path&#39;</span>     <span class="o">:</span> <span class="s1">&#39;/&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="c1">//打开地址
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">page</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">address</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">status</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 打开完毕
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="nx">status</span> <span class="o">===</span> <span class="s2">&#34;success&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="c1">// dom操作
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="kd">var</span> <span class="nx">rect</span> <span class="o">=</span> <span class="nx">page</span><span class="p">.</span><span class="nx">evaluate</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="kd">var</span> <span class="nx">html</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s1">&#39;html&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span><span class="p">(</span><span class="nx">html</span> <span class="o">&amp;&amp;</span> <span class="nx">html</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span><span class="p">(</span><span class="nx">html</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">innerHTML</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;id=&#34;contMain&#34;&#39;</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">                    <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="nx">offset</span> <span class="o">:</span> <span class="nx">html</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">getBoundingClientRect</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                    <span class="nx">innerHTML</span> <span class="o">:</span>  <span class="nx">html</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">innerHTML</span>   
</span></span><span class="line"><span class="cl">                <span class="p">};</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">});</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">rect</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">            <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">output</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="nx">page</span><span class="p">.</span><span class="nx">close</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">            <span class="nx">phantom</span><span class="p">.</span><span class="nx">exit</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">rect</span><span class="p">.</span><span class="nx">innerHTML</span><span class="p">);</span> <span class="c1">// 输出html
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="nx">page</span><span class="p">.</span><span class="nx">clipRect</span> <span class="o">=</span> <span class="p">{</span> <span class="c1">//设置截取区域(此设置为全屏)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>          <span class="nx">top</span><span class="o">:</span><span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">left</span><span class="o">:</span><span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">width</span><span class="o">:</span><span class="nx">rect</span><span class="p">.</span><span class="nx">offset</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">height</span><span class="o">:</span><span class="nx">rect</span><span class="p">.</span><span class="nx">offset</span><span class="p">.</span><span class="nx">height</span>
</span></span><span class="line"><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="cl">        <span class="nb">window</span><span class="p">.</span><span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">page</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">output</span><span class="p">);</span> <span class="c1">// 输出
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>          <span class="nx">page</span><span class="p">.</span><span class="nx">close</span><span class="p">();</span> <span class="c1">// 关闭
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>          <span class="nx">phantom</span><span class="p">.</span><span class="nx">exit</span><span class="p">();</span> <span class="c1">// 退出
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="p">},</span> <span class="mi">200</span><span class="p">);</span> 
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="配置文件总结">配置文件总结</h3>
<ul>
<li>output为输出方式， 为输出的绝对路径(例如:&lsquo;c:/123.jpg&rsquo;)， 以后缀决定文件格式. 建议使用pdf格式， pdf格式目前测试来看没有出现问题， 图片则出现过背景颜色丢失的情况</li>
<li>console.log(page.renderBase64(&lsquo;JPEG&rsquo;)) 以Base64的格式输出至控制台</li>
<li>这里是因为同时进行html爬取和截图快照， 所以不使用Base64的方式， 且输出的字符串有长度限制， 建议不要大量console.log()， 否则后面的内容可能会缺失</li>
<li>page.evaluate内可进行dom操作， 这里只取了html， 同理可有规则的针对爬取想要的页面信息</li>
<li>addCookie会返回一个boolean值， 有见到别人的文章判断了这个值才进行后续操作，  但我测试来看是有bug的， 即使成功也返回了false</li>
<li>可以利用dom操作获取元素的位置及宽高对clipRect进行设置， 可达对想要的区域截图的目的， 例如截取某个div中的内容</li>
</ul>
<h2 id="java封装">java封装</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">phantomjs</span><span class="p">(</span><span class="n">String</span><span class="w"> </span><span class="n">confPath</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">url</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">ssionId</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">outPath</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">StringBuilder</span><span class="w"> </span><span class="n">sb</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">StringBuilder</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">InputStream</span><span class="w"> </span><span class="n">is</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">InputStreamReader</span><span class="w"> </span><span class="n">isr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">BufferedReader</span><span class="w"> </span><span class="n">br</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">try</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">String</span><span class="w"> </span><span class="n">cmd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;phantomjs &#34;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">confPath</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">&#34; &#34;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">ssionId</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">&#34; &#34;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">url</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">&#34; &#34;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">outPath</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Process</span><span class="w"> </span><span class="n">ps</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Runtime</span><span class="p">.</span><span class="na">getRuntime</span><span class="p">().</span><span class="na">exec</span><span class="p">(</span><span class="n">cmd</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">is</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps</span><span class="p">.</span><span class="na">getInputStream</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">isr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">InputStreamReader</span><span class="p">(</span><span class="n">is</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;utf-8&#34;</span><span class="p">);</span><span class="w"> </span><span class="c1">// 注意编码格式</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">br</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">BufferedReader</span><span class="p">(</span><span class="n">isr</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">String</span><span class="w"> </span><span class="n">tmp</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">while</span><span class="w"> </span><span class="p">((</span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">br</span><span class="p">.</span><span class="na">readLine</span><span class="p">())</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="n">sb</span><span class="p">.</span><span class="na">append</span><span class="p">(</span><span class="n">tmp</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="n">IOException</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">e</span><span class="p">.</span><span class="na">printStackTrace</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="n">Exception</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">e</span><span class="p">.</span><span class="na">printStackTrace</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">finally</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">IOUtils</span><span class="p">.</span><span class="na">closeQuietly</span><span class="p">(</span><span class="n">br</span><span class="p">);</span><span class="w"> </span><span class="c1">// 注意关闭流</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">IOUtils</span><span class="p">.</span><span class="na">closeQuietly</span><span class="p">(</span><span class="n">isr</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">IOUtils</span><span class="p">.</span><span class="na">closeQuietly</span><span class="p">(</span><span class="n">is</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="n">String</span><span class="w"> </span><span class="n">html</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sb</span><span class="p">.</span><span class="na">toString</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">html</span><span class="p">.</span><span class="na">contains</span><span class="p">(</span><span class="n">filePath</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="n">html</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="java封装总结">java封装总结</h3>
<ul>
<li>我这里直接使用phantomjs是因为设置了环境变量， 否则请使用文件的绝对路径</li>
<li>编码格式尤为重要， 否则将出现html乱码问题</li>
</ul>
<h1 id="总结">总结</h1>
<p>phantomjs的功能非常强大，使用起来也是非常简单的。本文中只是一些简单的使用，更多的请自行查看<a href="http://phantomjs.org/api/webpage/" target="_blank" rel="noopener noreffer ">官方API</a>。</p>
<h1 id="致谢">致谢</h1>
<p>这是我第一篇hexo文章，在<a href="https://bingozb.github.io/51.html" target="_blank" rel="noopener noreffer ">Bingo phantomjs</a>的文章中得到了大量素材与灵感，以此致谢。</p>
</div><div class="post-footer" id="post-footer">
    <div class="post-info">
        <div class="post-info-line">
            <div class="post-info-mod">
                <span>Updated on 2018-01-29</span>
            </div></div>
        <div class="post-info-line">
            <div class="post-info-md"></div>
            <div class="post-info-share">
                <span><a href="javascript:void(0);" title="Share on Twitter" data-sharer="twitter" data-url="https://100180.xyz/posts/20180129/" data-title="java调用phantomjs爬取网页及快照" data-hashtags="phantomjs,爬虫,网页快照,javascript,java"><i class="fab fa-twitter fa-fw" aria-hidden="true"></i></a><a href="javascript:void(0);" title="Share on Facebook" data-sharer="facebook" data-url="https://100180.xyz/posts/20180129/" data-hashtag="phantomjs"><i class="fab fa-facebook-square fa-fw" aria-hidden="true"></i></a><a href="javascript:void(0);" title="Share on Linkedin" data-sharer="linkedin" data-url="https://100180.xyz/posts/20180129/"><i class="fab fa-linkedin fa-fw" aria-hidden="true"></i></a><a href="javascript:void(0);" title="Share on 微博" data-sharer="weibo" data-url="https://100180.xyz/posts/20180129/" data-title="java调用phantomjs爬取网页及快照"><i class="fab fa-weibo fa-fw" aria-hidden="true"></i></a><a href="javascript:void(0);" title="Share on 百度" data-sharer="baidu" data-url="https://100180.xyz/posts/20180129/" data-title="java调用phantomjs爬取网页及快照"><i data-svg-src="/lib/simple-icons/icons/baidu.min.svg" aria-hidden="true"></i></a><a href="javascript:void(0);" title="Share on Evernote" data-sharer="evernote" data-url="https://100180.xyz/posts/20180129/" data-title="java调用phantomjs爬取网页及快照"><i class="fab fa-evernote fa-fw" aria-hidden="true"></i></a><a href="javascript:void(0);" title="Share on Skype" data-sharer="skype" data-url="https://100180.xyz/posts/20180129/" data-title="java调用phantomjs爬取网页及快照"><i class="fab fa-skype fa-fw" aria-hidden="true"></i></a></span>
            </div>
        </div>
    </div>

    <div class="post-info-more">
        <section class="post-tags"><i class="fas fa-tags fa-fw" aria-hidden="true"></i>&nbsp;<a href="/tags/phantomjs/">Phantomjs</a>,&nbsp;<a href="/tags/%E7%88%AC%E8%99%AB/">爬虫</a>,&nbsp;<a href="/tags/%E7%BD%91%E9%A1%B5%E5%BF%AB%E7%85%A7/">网页快照</a>,&nbsp;<a href="/tags/javascript/">Javascript</a>,&nbsp;<a href="/tags/java/">Java</a></section>
        <section>
            <span><a href="javascript:void(0);" onclick="window.history.back();">Back</a></span>&nbsp;|&nbsp;<span><a href="/">Home</a></span>
        </section>
    </div>

    <div class="post-nav"><a href="/posts/20171220/" class="prev" rel="prev" title="Cmd Markdown 复制过来的语法测试"><i class="fas fa-angle-left fa-fw" aria-hidden="true"></i>Cmd Markdown 复制过来的语法测试</a>
            <a href="/posts/2018081401/" class="next" rel="next" title="CSS自定义滚动条(IE和chrome)">CSS自定义滚动条(IE和chrome)<i class="fas fa-angle-right fa-fw" aria-hidden="true"></i></a></div>
</div>
</article></div>
            </main><footer class="footer">
        <div class="footer-container"><div class="footer-line" itemscope itemtype="http://schema.org/CreativeWork"><i class="far fa-copyright fa-fw" aria-hidden="true"></i><span itemprop="copyrightYear">2017 - 2025</span><span class="author" itemprop="copyrightHolder">&nbsp;<a href="/" target="_blank">MidAug</a></span>&nbsp;|&nbsp;<span class="license"><a rel="license external nofollow noopener noreffer" href="https://creativecommons.org/licenses/by-nc/4.0/" target="_blank">CC BY-NC 4.0</a></span><span class="icp-splitter">&nbsp;|&nbsp;</span><br class="icp-br"/>
                    <span class="icp"><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-7196301099178927" crossorigin="anonymous"></script> <a target=_blank href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=31011502019261"><img style="vertical-align: text-bottom; height: 1rem" class="lazyload" data-src="/beian/gongan.png"><span>沪公网安备 31011502019261号</span></a><span class="icp-splitter">&nbsp;|&nbsp;</span><a href="https://beian.miit.gov.cn/" target="_blank">沪ICP备2022026688号-1</a></span></div>
        </div>
    </footer></div>

        <div id="fixed-buttons"><a href="#" id="back-to-top" class="fixed-button" title="Back to Top">
                <i class="fas fa-arrow-up fa-fw" aria-hidden="true"></i>
            </a><a href="#" id="view-comments" class="fixed-button" title="View Comments">
                <i class="fas fa-comment fa-fw" aria-hidden="true"></i>
            </a>
        </div><script type="text/javascript" src="/lib/autocomplete/autocomplete.min.js"></script><script type="text/javascript" src="/lib/lunr/lunr.min.js"></script><script type="text/javascript" src="/lib/lazysizes/lazysizes.min.js"></script><script type="text/javascript" src="/lib/clipboard/clipboard.min.js"></script><script type="text/javascript" src="/lib/sharer/sharer.min.js"></script><script type="text/javascript" src="/lib/typeit/index.umd.js"></script><script type="text/javascript">window.config={"code":{"copyTitle":"Copy to clipboard","maxShownLines":50},"comment":{},"data":{"id-1":"八月半的研发杂谈","id-2":"八月半的研发杂谈"},"search":{"highlightTag":"em","lunrIndexURL":"/index.json","maxResultLength":10,"noResultsFound":"No results found","snippetLength":80,"type":"lunr"},"typeit":{"cursorChar":"|","cursorSpeed":1000,"data":{"id-1":["id-1"],"id-2":["id-2"]},"duration":-1,"speed":30}};</script><script type="text/javascript" src="/js/theme.min.js"></script></body>
</html>
